OSDN Git Service

Initial Commit
[qcad/qcad.git] / qcadwin / QManager.cpp
1 //---------------------------------------------------------------------------\r
2 // Management class\r
3 //---------------------------------------------------------------------------\r
4 #include <iostream>\r
5 #include <fstream>\r
6 #include <sstream>\r
7 #include <algorithm>\r
8 #include "QManager.h"\r
9 #include "QCompilerCntl.h"\r
10 #include "QCalcManager.h"\r
11 #include "QBitbox.h"\r
12 #include "StrUtils.h"\r
13 #include "QUndoManager.h"\r
14 #include "undo/QUndoRemove.h"\r
15 #include "undo/QUndoAdd.h"\r
16 #include "undo/QUndoModify.h"\r
17 #include "undo/QUndoQuitSelect.h"\r
18 //---------------------------------------------------------------------------\r
19 const int QManager::DEFAULT_LINE = 7;\r
20 const int QManager::DEFAULT_COLUMN = 15;\r
21 //---------------------------------------------------------------------------\r
22 QManager::QManager(void) {\r
23   CircuitFlg = NULL;\r
24   Init(DEFAULT_LINE,DEFAULT_COLUMN);\r
25   qSelector = new QSelector();\r
26   qUndoManager = new QUndoManager();\r
27 }\r
28 //---------------------------------------------------------------------------\r
29 QManager::~QManager(void) {\r
30   InitCircuitFlg(0,0);\r
31   DeleteAll();\r
32   delete qSelector;\r
33   delete qUndoManager;\r
34 }\r
35 //---------------------------------------------------------------------------\r
36 void\r
37 QManager::Init(int Line, int Column) {\r
38   DeleteAll();\r
39   InitCircuitFlg(Line, Column);\r
40   LineNumber = Line;\r
41   ColumnNumber = Column;\r
42   StepLine = 0;\r
43   for (int i=0;i<LineNumber;i++) {\r
44     QBitbox *qbb = new QBitbox(i);\r
45     Add(qbb);\r
46   }\r
47   SetAllCircuitFlg();\r
48   Modified = false;\r
49   FileName = "";\r
50 }\r
51 //---------------------------------------------------------------------------\r
52 // Management of QCircuits\r
53 //---------------------------------------------------------------------------\r
54 void\r
55 QManager::DeleteAll(void) {\r
56   for (QList::iterator i=qList.begin();i!=qList.end();i++) {\r
57     QCircuit *qc = (*i);\r
58     delete qc;\r
59   }\r
60   qList.clear();\r
61 }\r
62 //---------------------------------------------------------------------------\r
63 int\r
64 QManager::GetQCircuitCount(void) {\r
65   return qList.size();\r
66 }\r
67 //---------------------------------------------------------------------------\r
68 QCircuit*\r
69 QManager::GetQCircuitAt(int index) {\r
70   return  qList[index];\r
71 };\r
72 //---------------------------------------------------------------------------\r
73 bool\r
74 QManager::Contains(QCircuit *qc) {\r
75   for (QList::iterator i=qList.begin();i!=qList.end();i++) {\r
76     QCircuit *q = (*i);\r
77     if(q == qc) {\r
78       return true;\r
79     }\r
80   }\r
81   return false;\r
82 }\r
83 //---------------------------------------------------------------------------\r
84 void\r
85 QManager::Add(QCircuit *qc) {\r
86   qList.push_back(qc);\r
87 }\r
88 //---------------------------------------------------------------------------\r
89 void\r
90 QManager::Remove(QCircuit *qc) {\r
91   qList.erase(remove(qList.begin(), qList.end(), qc), qList.end());\r
92   delete qc;\r
93 }\r
94 //---------------------------------------------------------------------------\r
95 void\r
96 QManager::AddCircuit(QCircuit *qc) {\r
97   Add(qc);\r
98   if (qc->GetType() != QC_BITBOX) {\r
99     qUndoManager->Add(new QUndoAdd(qc));\r
100   }\r
101   SetAllCircuitFlg();\r
102   Modified = true;\r
103 }\r
104 //---------------------------------------------------------------------------\r
105 void\r
106 QManager::RemoveCircuit(QCircuit *qc) {\r
107   qUndoManager->Add(new QUndoRemove(qc));\r
108   Remove(qc);\r
109   SetAllCircuitFlg();\r
110   Modified = true;\r
111 }\r
112 //---------------------------------------------------------------------------\r
113 // Methods for CircuitFlg\r
114 //---------------------------------------------------------------------------\r
115 void\r
116 QManager::InitCircuitFlg(int Line, int Column) {\r
117 \r
118   if (CircuitFlg != NULL) {\r
119     for (int i = 0; i < this->ColumnNumber; i++) delete [] CircuitFlg[i];\r
120     delete [] CircuitFlg;\r
121   }\r
122   CircuitFlg = new int*[Column];\r
123   for (int i = 0; i < Column; i++) {\r
124     CircuitFlg[i] = new int[Line];\r
125     for (int j = 0; j < Line; j++) {\r
126       CircuitFlg[i][j] = FALSE;\r
127     }\r
128   }\r
129 }\r
130 //---------------------------------------------------------------------------\r
131 QCircuit*\r
132 QManager::GetCircuitInclude(int x, int y) {\r
133 \r
134   if(x <0 || x >GetColumnNumber()){\r
135     return NULL;\r
136   }\r
137 \r
138   if(y <0 || y >GetLineNumber()){\r
139     return NULL;\r
140   }\r
141 \r
142   int index = CircuitFlg[x][y];\r
143   if (index == QC_NULL) {\r
144     return NULL;\r
145   } else {\r
146     return GetQCircuitAt(index);\r
147   }\r
148 }\r
149 //---------------------------------------------------------------------------\r
150 void\r
151 QManager::SetAllCircuitFlg(void) {\r
152   for (int x = 0; x < ColumnNumber; x++) {\r
153     for (int y = 0; y < LineNumber; y++) {\r
154       CircuitFlg[x][y] = QC_NULL;\r
155     }\r
156   }\r
157 \r
158   for (int i = 0; i < GetQCircuitCount(); i++) {\r
159     QCircuit *qc = GetQCircuitAt(i);\r
160     TRect rc = qc->GetOccupiedRect();\r
161     for (int x = rc.left; x < rc.right; x++) {\r
162       for (int y = rc.top; y < rc.bottom; y++) {\r
163         CircuitFlg[x][y] = i;\r
164       }\r
165     }\r
166   }\r
167 }\r
168 //---------------------------------------------------------------------------\r
169 void\r
170 QManager::ClrCircuitFlg(QCircuit* qc) {\r
171   TRect rc = qc->GetOccupiedRect();\r
172   for (int x = rc.left; x < rc.right; x++) {\r
173     for (int y = rc.top; y < rc.bottom; y++) {\r
174       CircuitFlg[x][y] = QC_NULL;\r
175     }\r
176   }\r
177 }\r
178 //---------------------------------------------------------------------------\r
179 bool\r
180 QManager::CanPutCircuit(QCircuit* qc) {\r
181   TRect rc = qc->GetOccupiedRect();\r
182   for (int x = rc.left; x < rc.right; x++) {\r
183     for (int y = rc.top; y < rc.bottom; y++) {\r
184       if (CircuitFlg[x][y] != QC_NULL) return FALSE;\r
185     }\r
186   }\r
187   return TRUE;\r
188 }\r
189 //---------------------------------------------------------------------------\r
190 // Interfaces\r
191 //---------------------------------------------------------------------------\r
192 void\r
193 QManager::SaveToFile(char * filename) {\r
194 \r
195   ofstream ofs(filename);\r
196   ofs << "#QCAD - SaveData" << endl;\r
197   ofs << LineNumber << endl;\r
198   ofs << ColumnNumber << endl;\r
199   for (int i=0;i<GetQCircuitCount();i++) {\r
200     QCircuit *qc = GetQCircuitAt(i);\r
201     ofs << qc->GetSaveText().c_str() << endl;\r
202   }\r
203   ofs.close();\r
204   //Save Intermediate code automatically\r
205   SaveMidCode(filename);\r
206   Modified = false;\r
207   FileName = filename;\r
208 }\r
209 //---------------------------------------------------------------------------\r
210 void\r
211 QManager::LoadFromFile(const char *filename) {\r
212 \r
213   ifstream ifs;\r
214   ifs.open(filename,ios::in);
215   vector<string> v;
216   string sVersion,sLine,sColumn;
217   getline(ifs,sVersion);
218   getline(ifs,sLine);
219   getline(ifs,sColumn);
220   int l = atoi(sLine.c_str());
221   int c = atoi(sColumn.c_str());
222
223   Init(l,c);
224   DeleteAll();\r
225   string line;
226   while(getline(ifs,line)){
227     v = StrUtils::split_str(line);
228     int x = atoi(v[0].c_str());
229     int y = atoi(v[1].c_str());
230     string TypeStr = v[2];
231     string Param = v[3].substr(1,v[3].length()-2);
232     QCircuit *qc = QCircuit::Create(TypeStr,x,y,Param.c_str());
233     Add(qc);\r
234   }
235   FileName = filename;
236   Modified = false;
237   SetAllCircuitFlg();\r
238 }\r
239 //---------------------------------------------------------------------------\r
240 /**\r
241  * Save Intermediate code.\r
242  */\r
243 void\r
244 QManager::SaveMidCode(char * _filename) {\r
245   string filename = _filename;\r
246   unsigned int p = filename.find_last_of(".");\r
247   if(p!=filename.length()){\r
248     filename.replace(p,4,".mcd");\r
249   }else{\r
250     filename+=".mcd";\r
251   }\r
252 \r
253   ofstream ofs(filename.c_str());\r
254   ofs << "# file name: \"" << filename << "\"" << endl;\r
255   ofs << "# QCAD MIDCODE" << endl;\r
256   ofs << GetCalcText() << endl;\r
257   ofs.close();\r
258 }\r
259 //---------------------------------------------------------------------------\r
260 /**\r
261  * Remove Selected Circuits\r
262  */\r
263 void\r
264 QManager::RemoveSelectedCircuits(QDraw *qDraw) {\r
265   QUndoRemove *qu = new QUndoRemove();\r
266   for (int i=0;i<qSelector->GetSelectedCount();i++) {\r
267     QCircuit *qc = qSelector->GetSelectedCircuit(i);\r
268     if (qc->GetType() != QC_BITBOX) {\r
269       qu->Add(qc);\r
270       Remove(qc);\r
271     }\r
272   }\r
273   qUndoManager->Add(qu);\r
274   qSelector->DeleteAll();\r
275   SetAllCircuitFlg();\r
276   DrawAll(qDraw);\r
277 }\r
278 //---------------------------------------------------------------------------\r
279 QCircuit*\r
280 QManager::GetQCircuitAt(int x,int y) {\r
281   for (int i=0;i<GetQCircuitCount();i++) {\r
282     QCircuit *qc = GetQCircuitAt(i);\r
283     if (x==qc->GetX() && y == qc->GetY()) {\r
284       return qc;\r
285     }\r
286   }\r
287   return NULL;\r
288 }\r
289 //---------------------------------------------------------------------------\r
290 void\r
291 QManager::Undo(QDraw *qDraw) {\r
292   if (qUndoManager->GetUndoCount()==0) {\r
293     return;\r
294   }\r
295   qUndoManager->Undo(qDraw,this);\r
296   SetAllCircuitFlg();\r
297   DrawAll(qDraw);\r
298   Modified = true;\r
299 }\r
300 //---------------------------------------------------------------------------\r
301 void\r
302 QManager::ReverseAll(void) {\r
303   for (int i=0;i<GetQCircuitCount();i++) {\r
304     QCircuit *qc = GetQCircuitAt(i);\r
305     qc->Reverse(LineNumber-1);\r
306   }\r
307 }\r
308 //---------------------------------------------------------------------------\r
309 // Drawing Methods\r
310 //---------------------------------------------------------------------------\r
311 void\r
312 QManager::DrawGridPrinter(QDraw *qDraw) {\r
313   int GridSize = qDraw->GetGridSize();\r
314 \r
315   int Width = ColumnNumber*GridSize;\r
316   int Height = LineNumber*GridSize;\r
317 \r
318   qDraw->SetBrushColor(clWhite);\r
319   qDraw->FillRect(0,0,Width,Height);\r
320 \r
321   // Draw holizontal lines of circuit\r
322   qDraw->SetPenColor(clGray);\r
323   for (int i=0;i<LineNumber;i++) {\r
324     qDraw->DrawLine(0,i*GridSize+GridSize/2,Width,i*GridSize+GridSize/2);\r
325   }\r
326 \r
327   // Draw vertical lines for each grid\r
328   if (PrtSt.ShowVtLineFlg) {\r
329     for (int i=0;i<LineNumber;i++) {\r
330       int y = i*GridSize+GridSize/2;\r
331       for (int j=0;j<ColumnNumber;j++) {\r
332         int x = j*GridSize+ GridSize/2;\r
333         qDraw->DrawLine(x,y-GridSize/4,x,y+GridSize/4);\r
334       }\r
335     }\r
336   }\r
337 \r
338   //Write Bit number\r
339   if (PrtSt.ShowIndexFlg) {\r
340     for (int i = 0; i < LineNumber; i++) {\r
341       ostringstream os;\r
342       os << "Q" << (i+1);\r
343       qDraw->TextOut(-GridSize/2,i*GridSize + GridSize/2,os.str());\r
344     }\r
345   }\r
346 }\r
347 //---------------------------------------------------------------------------\r
348 void\r
349 QManager::DrawStepBar(QDraw *qDraw) {\r
350   int GridSize = qDraw->GetGridSize();\r
351   int x1 = StepLine * GridSize;\r
352   int Height = LineNumber*GridSize-1;\r
353   int x2 = x1 + GridSize;\r
354 \r
355   qDraw->SetBrushColor(clRed);\r
356   qDraw->DrawLine(x1,0,x1,Height);\r
357   qDraw->DrawLine(x2,0,x2,Height);\r
358   qDraw->DrawLine(x1,0,x2,0);\r
359   qDraw->DrawLine(x1,Height,x2,Height);\r
360 }\r
361 //---------------------------------------------------------------------------\r
362 void\r
363 QManager::DrawAll(QDraw *qDraw) {\r
364   qDraw->DrawGrid(ColumnNumber,LineNumber);\r
365   for (int i=0;i<GetQCircuitCount();i++) {\r
366     QCircuit *qc = GetQCircuitAt(i);\r
367     qc->Draw(qDraw);\r
368   }\r
369   qSelector->Select(qDraw);\r
370 }\r
371 //---------------------------------------------------------------------------\r
372 void\r
373 QManager::DrawAllPrinter(QDraw *qDraw) {\r
374   DrawGridPrinter(qDraw);\r
375   for (int i=0;i<GetQCircuitCount();i++) {\r
376     QCircuit *qc = GetQCircuitAt(i);\r
377     qc->Draw(qDraw);\r
378   }\r
379 }\r
380 //---------------------------------------------------------------------------\r
381 // Methods for Calculation\r
382 //---------------------------------------------------------------------------\r
383 string\r
384 QManager::GetCalcText(void) {\r
385 \r
386   ostringstream os;\r
387   os << "INIT(" << LineNumber << ")" << endl;\r
388   for (int i=0;i<ColumnNumber;i++) {\r
389     for (int j=0;j<LineNumber;j++) {\r
390       QCircuit *qc = GetQCircuitAt(i,j);\r
391       if (qc == NULL || qc->GetCalcText() == "blank") {\r
392         continue;\r
393       }\r
394       os << qc->GetCalcText().c_str() << endl;\r
395     }\r
396   }\r
397   return os.str();\r
398 }\r
399 //---------------------------------------------------------------------------\r
400 void\r
401 QManager::CalcAll(QBits *qBits) {\r
402   istringstream iss(GetCalcText().c_str());\r
403   QCalcManager *qCalcManager = new QCalcManager(iss);\r
404   qCalcManager->Calc(qBits);\r
405   delete qCalcManager;\r
406 }\r
407 //---------------------------------------------------------------------------\r
408 /**\r
409  * For step by step calculation\r
410  */\r
411 void\r
412 QManager::CalcAt(QBits *qBits,int Line) {\r
413   //TODO:\r
414 }\r
415 //---------------------------------------------------------------------------\r
416 /**\r
417  * For step by step calculation\r
418  */\r
419 void\r
420 QManager::CalcStep(QBits *qBits,QDraw *qDraw) {\r
421   //TODO:\r
422   DrawAll(qDraw);\r
423   DrawStepBar(qDraw);\r
424 }\r
425 //---------------------------------------------------------------------------\r
426 // Export PostScript\r
427 //---------------------------------------------------------------------------\r
428 void\r
429 QManager::SaveAsEPS(const char *filename) {\r
430 \r
431   QPSDraw *psDraw = new QPSDraw();\r
432   DrawAllPS(psDraw);\r
433   ofstream ofs(filename);\r
434   ofs << psDraw->GetText();\r
435   ofs.close();\r
436   delete psDraw;\r
437 }\r
438 //---------------------------------------------------------------------------\r
439 void\r
440 QManager::DrawAllPS(QPSDraw *psDraw) {\r
441 \r
442   int GridSize = psDraw->GetGridSize();\r
443   int Width = ColumnNumber*GridSize;\r
444   int Height = LineNumber*GridSize;\r
445   psDraw->SetWidth(Width);\r
446   psDraw->SetHeight(Height);\r
447 \r
448   ReverseAll();\r
449 \r
450   for (int i=0;i<LineNumber;i++) {\r
451     QBitbox *qb = (QBitbox*)GetQCircuitAt(0,i);\r
452     psDraw->DrawGrid(i,qb->Enabled);\r
453   }\r
454 \r
455   for (int i=0;i<GetQCircuitCount();i++) {\r
456     QCircuit *qc = GetQCircuitAt(i);\r
457     qc->DrawPS(psDraw);\r
458   }\r
459   ReverseAll();\r
460 }\r
461 //---------------------------------------------------------------------------\r
462 void\r
463 QManager::AddSelect(QCircuit *qc, QDraw *qDraw) {\r
464   if (qSelector->GetSelectedCount() == 0) {\r
465     QUndoQuitSelect *qu = new QUndoQuitSelect(qSelector);\r
466     qUndoManager->Add(qu);\r
467   }\r
468   qSelector->AddRemove(qc);\r
469   DrawAll(qDraw);\r
470 }\r
471 //---------------------------------------------------------------------------\r
472 void\r
473 QManager::RemoveSelect(QDraw *qDraw) {\r
474   if (qSelector->GetSelectedCount() != 0) {\r
475     QUndoQuitSelect *qu = new QUndoQuitSelect(qSelector);\r
476     qUndoManager->Add(qu);\r
477     qSelector->DeleteAll();\r
478     DrawAll(qDraw);\r
479   }\r
480 }\r
481 //---------------------------------------------------------------------------\r
482 void\r
483 QManager::ModifyCircuit(QCircuit * qc0, QCircuit* qc1) {\r
484   Modified = true;\r
485   QUndoModify * qu = new QUndoModify(qc0, qc1);\r
486   qUndoManager->Add(qu);\r
487 }\r
488 //---------------------------------------------------------------------------\r
489 void\r
490 QManager::Swap(QCircuit * qc0, QCircuit * qc1) {\r
491 \r
492   if(Contains(qc0)) {\r
493     Remove(qc0);\r
494   }\r
495   Add(qc1);\r
496   delete qc0;\r
497 \r
498 }\r
499 //---------------------------------------------------------------------------\r
500 void\r
501 QManager::InsertColumn(int x, int width) {\r
502   Modified = true;\r
503   ColumnNumber = GetColumnNumber() + width;\r
504   StepLine = 0;\r
505   for (int i = 0; i < GetQCircuitCount(); i++) {\r
506     QCircuit *qc = GetQCircuitAt(i);\r
507     if (x <= qc->GetX()) {\r
508       qc->SetX(qc->GetX() + width);\r
509     }\r
510   }\r
511   SetAllCircuitFlg();\r
512 }\r
513 //---------------------------------------------------------------------------\r
514 \r