scidavis  2.3.0
About: SciDAVis is a free application for Scientific Data Analysis and Visualization (a fork off of QtiPlot).
  Fossies Dox: scidavis-2.3.0.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

AbstractAspect.cpp
Go to the documentation of this file.
1 
11 
29 #include "core/AbstractAspect.h"
30 #include "core/AspectPrivate.h"
31 #include "core/aspectcommands.h"
32 #include "core/future_Folder.h"
33 #include "lib/XmlStreamReader.h"
34 
35 #include <QIcon>
36 #include <QMenu>
37 #include <QMessageBox>
38 #include <QStyle>
39 #include <QApplication>
40 #include <QXmlStreamWriter>
41 
43  : d_aspect_private(new Private(this, name))
44 {
45 }
46 
48 {
49  delete d_aspect_private;
50 }
51 
52 void AbstractAspect::writeCommentElement(QXmlStreamWriter * writer) const
53 {
54  writer->writeStartElement("comment");
55  QString temp = comment();
56  temp.replace("\n", "\\n");
57  writer->writeCDATA(temp);
58  writer->writeEndElement();
59 }
60 
62 {
63  Q_ASSERT(reader->isStartElement() && reader->name() == "comment");
64  QString temp = reader->readElementText();
65  temp.replace("\\n", "\n");
66  setComment(temp);
67  return true;
68 }
69 
70 void AbstractAspect::writeBasicAttributes(QXmlStreamWriter * writer) const
71 {
72  writer->writeAttribute("creation_time" , creationTime().toString("yyyy-dd-MM hh:mm:ss:zzz"));
73  writer->writeAttribute("caption_spec", captionSpec());
74  writer->writeAttribute("name", name());
75 }
76 
78 {
79  QString prefix(tr("XML read error: ","prefix for XML error messages"));
80  QString postfix(tr(" (non-critical)", "postfix for XML error messages"));
81 
82  QXmlStreamAttributes attribs = reader->attributes();
83  QString str;
84 
85  // read name
86  str = attribs.value(reader->namespaceUri().toString(), "name").toString();
87  if(str.isEmpty())
88  {
89  reader->raiseWarning(prefix+tr("aspect name missing or empty")+postfix);
90  }
91  setName(str);
92  // read creation time
93  str = attribs.value(reader->namespaceUri().toString(), "creation_time").toString();
94  QDateTime creation_time = QDateTime::fromString(str, "yyyy-dd-MM hh:mm:ss:zzz");
95  if(str.isEmpty() || !creation_time.isValid())
96  {
97  reader->raiseWarning(tr("Invalid creation time for '%1'. Using current time.").arg(name()));
98  setCreationTime(QDateTime::currentDateTime());
99  }
100  else
101  setCreationTime(creation_time);
102  // read caption spec
103  str = attribs.value(reader->namespaceUri().toString(), "caption_spec").toString();
105 
106  return true;
107 }
108 
110 {
111  return d_aspect_private->parent();
112 }
113 
115 {
116  Q_CHECK_PTR(child);
117  QString new_name = d_aspect_private->uniqueNameFor(child->name());
118  beginMacro(tr("%1: add %2.").arg(name()).arg(new_name));
119  if (new_name != child->name()) {
120  info(tr("Renaming \"%1\" to \"%2\" in order to avoid name collision.").arg(child->name()).arg(new_name));
121  child->setName(new_name);
122  }
125  endMacro();
126 }
127 
129 {
130  Q_CHECK_PTR(child);
131  QString new_name = d_aspect_private->uniqueNameFor(child->name());
132  beginMacro(tr("%1: insert %2 at position %3.").arg(name()).arg(new_name).arg(index+1));
133  if (new_name != child->name()) {
134  info(tr("Renaming \"%1\" to \"%2\" in order to avoid name collision.").arg(child->name()).arg(new_name));
135  child->setName(new_name);
136  }
139  endMacro();
140 }
141 
143 {
144  Q_ASSERT(indexOfChild(child) != -1);
145  beginMacro(tr("%1: remove %2.").arg(name()).arg(child->name()));
148  endMacro();
149 }
150 
152 {
153  Q_ASSERT(new_parent != NULL);
154  reparentChild(new_parent, child, new_parent->childCount());
155 }
156 
157 void AbstractAspect::reparentChild(AbstractAspect *new_parent, AbstractAspect *child, int new_index)
158 {
159  Q_ASSERT(indexOfChild(child) != -1);
160  Q_ASSERT(new_index > 0 && new_index <= new_parent->childCount());
161  Q_ASSERT(new_parent != NULL);
162  QString new_name = new_parent->d_aspect_private->uniqueNameFor(child->name());
163  beginMacro(tr("%1: move %2 to %3.").arg(name()).arg(child->name()).arg(new_parent->name()));
164  if (new_name != child->name()) {
165  info(tr("Renaming \"%1\" to \"%2\" in order to avoid name collision.").arg(child->name()).arg(new_name));
166  child->setName(new_name);
167  }
169  exec(new AspectChildReparentCmd(d_aspect_private, new_parent->d_aspect_private, child, new_index));
170  new_parent->completeAspectInsertion(child, new_index);
171  endMacro();
172 }
173 
175 {
176  Q_ASSERT(index >= 0 && index <= childCount());
178 }
179 
181 {
182  Q_ASSERT(index >= 0 && index <= childCount());
183  return d_aspect_private->child(index);
184 }
185 
187 {
188  return d_aspect_private->childCount();
189 }
190 
192 {
194 }
195 
196 void AbstractAspect::moveChild(int from, int to)
197 {
198  Q_ASSERT(0 <= from && from < d_aspect_private->childCount());
199  Q_ASSERT(0 <= to && to < d_aspect_private->childCount());
200  exec(new AspectChildMoveCmd(d_aspect_private, from, to));
201 }
202 
203 void AbstractAspect::exec(QUndoCommand *cmd)
204 {
205  Q_CHECK_PTR(cmd);
206  QUndoStack *stack = undoStack();
207  if (stack)
208  stack->push(cmd);
209  else {
210  cmd->redo();
211  delete cmd;
212  }
213 }
214 
215 void AbstractAspect::beginMacro(const QString& text)
216 {
217  QUndoStack *stack = undoStack();
218  if (stack)
219  stack->beginMacro(text);
220 }
221 
223 {
224  QUndoStack *stack = undoStack();
225  if (stack)
226  stack->endMacro();
227 }
228 
229 QString AbstractAspect::name() const
230 {
231  return d_aspect_private->name();
232 }
233 
234 void AbstractAspect::setName(const QString &value)
235 {
236  if (value.isEmpty()) {
237  setObjectName("1");
238  return;
239  }
240  if (value == d_aspect_private->name()) return;
241  // Until we get around to completely sanitizing the project file format, we have to remove
242  // characters that can easily break file save/restore.
243  // FIXME: once the project file format is fully XML-based (i.e. able to escape special characters),
244  // this can be removed
245  QString sanitized_value = value;
246  sanitized_value.remove(QChar('\n'));
247  sanitized_value.remove(QChar('\r'));
248  sanitized_value.remove(QChar('\t'));
249  if (sanitized_value != value)
250  info(tr("Tabs and line breaks in object names are currently not supported. They have been removed."));
251  if (d_aspect_private->parent()) {
252  QString new_name = d_aspect_private->parent()->uniqueNameFor(sanitized_value);
253  if (new_name != sanitized_value)
254  info(tr("Intended name \"%1\" diverted to \"%2\" in order to avoid name collision.").arg(sanitized_value).arg(new_name));
255  exec(new AspectNameChangeCmd(d_aspect_private, new_name));
256  } else
257  exec(new AspectNameChangeCmd(d_aspect_private, sanitized_value));
258 }
259 
260 QString AbstractAspect::comment() const
261 {
262  return d_aspect_private->comment();
263 }
264 
265 void AbstractAspect::setComment(const QString &value)
266 {
267  if (value == d_aspect_private->comment()) return;
269 }
270 
272 {
273  return d_aspect_private->captionSpec();
274 }
275 
276 void AbstractAspect::setCaptionSpec(const QString &value)
277 {
278  if (value == d_aspect_private->captionSpec()) return;
280 }
281 
282 void AbstractAspect::setCreationTime(const QDateTime& time)
283 {
284  if (time == d_aspect_private->creationTime()) return;
286 }
287 
289 {
290  return d_aspect_private->creationTime();
291 }
292 
293 QString AbstractAspect::caption() const
294 {
295  return d_aspect_private->caption();
296 }
297 
298 QIcon AbstractAspect::icon() const
299 {
300  return QIcon();
301 }
302 
304 {
305  QMenu * menu = new QMenu();
306 
307  const QStyle *widget_style = qApp->style();
308  QAction *action_temp;
309 
310  action_temp = menu->addAction(QObject::tr("&Remove"), this, SLOT(remove()));
311  action_temp->setIcon(widget_style->standardIcon(QStyle::SP_TrashIcon));
312 
313  return menu;
314 }
315 
317 {
318  if(inherits("future::Folder")) return static_cast<future::Folder *>(this);
319  AbstractAspect * parent_aspect = parentAspect();
320  while(parent_aspect && !parent_aspect->inherits("future::Folder"))
321  parent_aspect = parent_aspect->parentAspect();
322  return static_cast<future::Folder *>(parent_aspect);
323 }
324 
326 {
327  if(other == this) return true;
328  AbstractAspect * parent_aspect = parentAspect();
329  while(parent_aspect)
330  {
331  if(parent_aspect == other) return true;
332  parent_aspect = parent_aspect->parentAspect();
333  }
334  return false;
335 }
336 
337 QString AbstractAspect::uniqueNameFor(const QString &current_name) const
338 {
339  return d_aspect_private->uniqueNameFor(current_name);
340 }
341 
342 QList<AbstractAspect *> AbstractAspect::descendantsThatInherit(const char * class_name)
343 {
344  QList<AbstractAspect *> list;
345  if (inherits(class_name))
346  list << this;
347  for (int i=0; i<childCount(); i++)
348  list << child(i)->descendantsThatInherit(class_name);
349  return list;
350 }
351 
353 {
354  beginMacro(tr("%1: remove all children.").arg(name()));
355  for (int i=childCount()-1; i >= 0; i--)
356  removeChild(i);
357  endMacro();
358 }
359 
360 QVariant AbstractAspect::global(const QString &key)
361 {
362  QString qualified_key = QString(staticMetaObject.className()) + "/" + key;
363  QVariant result = Private::g_settings->value(qualified_key);
364  if (result.isValid())
365  return result;
366  else
367  return Private::g_defaults[qualified_key];
368 }
369 
370 void AbstractAspect::setGlobal(const QString &key, const QVariant &value)
371 {
372  Private::g_settings->setValue(QString(staticMetaObject.className()) + "/" + key, value);
373 }
374 
375 void AbstractAspect::setGlobalDefault(const QString &key, const QVariant &value)
376 {
377  Private::g_defaults[QString(staticMetaObject.className()) + "/" + key] = value;
378 }
379 
AspectNameChangeCmd
Definition: aspectcommands.h:36
AbstractAspect::Private::comment
QString comment() const
Definition: AspectPrivate.cpp:134
AbstractAspect::writeCommentElement
void writeCommentElement(QXmlStreamWriter *writer) const
Save the comment to XML.
Definition: AbstractAspect.cpp:52
AbstractAspect::reparentChild
void reparentChild(AbstractAspect *new_parent, AbstractAspect *child, int d_new_index)
Move a child to another aspect and transfer ownership.
Definition: AbstractAspect.cpp:157
future_Folder.h
AbstractAspect::Private::captionSpec
QString captionSpec() const
Definition: AspectPrivate.cpp:146
AbstractAspect::Private::caption
QString caption() const
Definition: AspectPrivate.cpp:171
AbstractAspect::exec
void exec(QUndoCommand *command)
Execute the given command, pushing it on the undoStack() if available.
Definition: AbstractAspect.cpp:203
AbstractAspect::global
static QVariant global(const QString &key)
Retrieve a global setting.
Definition: AbstractAspect.cpp:360
AbstractAspect::createContextMenu
virtual QMenu * createContextMenu() const
Return a new context menu.
Definition: AbstractAspect.cpp:303
str
#define str(x)
Definition: PythonScripting.cpp:41
XmlStreamReader
XML stream parser that supports errors as well as warnings.
Definition: XmlStreamReader.h:42
AbstractAspect::setComment
void setComment(const QString &value)
Definition: AbstractAspect.cpp:265
AbstractAspect::moveChild
void moveChild(int from, int to)
Change the positon of a child in my list of children.
Definition: AbstractAspect.cpp:196
AbstractAspect::insertChild
void insertChild(AbstractAspect *child, int index)
Insert the given Aspect at a specific position in my list of children.
Definition: AbstractAspect.cpp:128
AbstractAspect::Private::uniqueNameFor
QString uniqueNameFor(const QString &current_name) const
Definition: AspectPrivate.cpp:201
AbstractAspect::removeAllChildAspects
virtual void removeAllChildAspects()
Remove all child aspects.
Definition: AbstractAspect.cpp:352
AbstractAspect::Private::childCount
int childCount() const
Definition: AspectPrivate.cpp:111
AbstractAspect::index
int index() const
Return my position in my parent's list of children.
Definition: AbstractAspect.h:137
AbstractAspect::creationTime
QDateTime creationTime() const
Definition: AbstractAspect.cpp:288
AspectChildAddCmd
Definition: aspectcommands.h:154
toString
S toString(const QString &x)
Deal with conversion between QString and std::string/std::wstring in a generic way.
AspectChildMoveCmd
Definition: aspectcommands.h:168
AbstractAspect::d_aspect_private
Private * d_aspect_private
Definition: AbstractAspect.h:310
AbstractAspect::isDescendantOf
bool isDescendantOf(AbstractAspect *other)
Return whether the there is a path upwards to the given aspect.
Definition: AbstractAspect.cpp:325
AbstractAspect::descendantsThatInherit
QList< AbstractAspect * > descendantsThatInherit(const char *class_name)
Get all descendents that inherit the given class.
Definition: AbstractAspect.cpp:342
future::Folder
Folder in a project.
Definition: future_Folder.h:38
AbstractAspect::uniqueNameFor
QString uniqueNameFor(const QString &current_name) const
Make the specified name unique among my children by incrementing a trailing number.
Definition: AbstractAspect.cpp:337
AbstractAspect::icon
virtual QIcon icon() const
Return an icon to be used for decorating my views.
Definition: AbstractAspect.cpp:298
AbstractAspect::Private::indexOfChild
int indexOfChild(const AbstractAspect *child) const
Definition: AspectPrivate.cpp:91
aspectcommands.h
AbstractAspect::indexOfChild
int indexOfChild(const AbstractAspect *child) const
Return the position of child in my list of children.
Definition: AbstractAspect.cpp:191
AbstractAspect::~AbstractAspect
virtual ~AbstractAspect()
Definition: AbstractAspect.cpp:47
AbstractAspect::endMacro
void endMacro()
End the undo stack macro.
Definition: AbstractAspect.cpp:222
AbstractAspect::captionSpec
QString captionSpec() const
Return the specification string used for constructing the caption().
Definition: AbstractAspect.cpp:271
AbstractAspect::Private::g_defaults
static QHash< QString, QVariant > g_defaults
Definition: AspectPrivate.h:70
AbstractAspect::beginMacro
void beginMacro(const QString &text)
Begin an undo stack macro (series of commands)
Definition: AbstractAspect.cpp:215
AspectCaptionSpecChangeCmd
Definition: aspectcommands.h:78
AspectCommentChangeCmd
Definition: aspectcommands.h:57
AbstractAspect::childCount
int childCount() const
Return the number of child Aspects.
Definition: AbstractAspect.cpp:186
AbstractAspect::caption
QString caption() const
Definition: AbstractAspect.cpp:293
AbstractAspect::completeAspectInsertion
virtual void completeAspectInsertion(AbstractAspect *aspect, int index)
Called after a new child has been inserted or added.
Definition: AbstractAspect.h:294
AspectPrivate.h
AbstractAspect::Private
Private data managed by AbstractAspect.
Definition: AspectPrivate.h:42
AbstractAspect::name
QString name() const
Definition: AbstractAspect.cpp:229
AbstractAspect::readBasicAttributes
bool readBasicAttributes(XmlStreamReader *reader)
Load name, creation time and caption spec from XML.
Definition: AbstractAspect.cpp:77
AbstractAspect::child
AbstractAspect * child(int index) const
Get a child by its position in my list of children.
Definition: AbstractAspect.cpp:180
XmlStreamReader.h
AbstractAspect::Private::name
QString name() const
Definition: AspectPrivate.cpp:122
AbstractAspect::undoStack
virtual QUndoStack * undoStack() const
Return the undo stack of the Project, or 0 if this Aspect is not part of a Project.
Definition: AbstractAspect.h:182
AspectChildReparentCmd
Definition: aspectcommands.h:195
AbstractAspect::parentAspect
AbstractAspect * parentAspect() const
Return my parent Aspect or 0 if I currently don't have one.
Definition: AbstractAspect.cpp:109
AbstractAspect::setGlobalDefault
static void setGlobalDefault(const QString &key, const QVariant &value)
Set default value for a global setting.
Definition: AbstractAspect.cpp:375
AbstractAspect::writeBasicAttributes
void writeBasicAttributes(QXmlStreamWriter *writer) const
Save name, creation time and caption spec to XML.
Definition: AbstractAspect.cpp:70
AbstractAspect::folder
future::Folder * folder()
Return the folder the Aspect is contained in or 0 if not.
Definition: AbstractAspect.cpp:316
AbstractAspect::removeChild
void removeChild(AbstractAspect *child, bool detach=false)
Remove the given Aspect from my list of children.
Definition: AbstractAspect.cpp:142
AbstractAspect::Private::creationTime
QDateTime creationTime() const
Definition: AspectPrivate.cpp:196
AbstractAspect::setCaptionSpec
void setCaptionSpec(const QString &value)
Set the specification string used for constructing the caption().
Definition: AbstractAspect.cpp:276
AbstractAspect::Private::parent
AbstractAspect * parent()
Definition: AspectPrivate.h:65
AbstractAspect::setName
void setName(const QString &value)
Definition: AbstractAspect.cpp:234
name
char * name()
Definition: exp_saturation.c:45
AbstractAspect::comment
QString comment() const
Definition: AbstractAspect.cpp:260
AspectChildRemoveCmd
Definition: aspectcommands.h:122
AbstractAspect::Private::child
AbstractAspect * child(int index)
Definition: AspectPrivate.cpp:116
AbstractAspect::addChild
void addChild(AbstractAspect *child)
Add the given Aspect to my list of children.
Definition: AbstractAspect.cpp:114
AbstractAspect::remove
virtual void remove()
Remove me from my parent's list of children.
Definition: AbstractAspect.h:250
AbstractAspect::setGlobal
static void setGlobal(const QString &key, const QVariant &value)
Update a global setting.
Definition: AbstractAspect.cpp:370
AbstractAspect::AbstractAspect
AbstractAspect(const QString &name)
Definition: AbstractAspect.cpp:42
AbstractAspect::setCreationTime
void setCreationTime(const QDateTime &time)
Set the creation time.
Definition: AbstractAspect.cpp:282
XmlStreamReader::raiseWarning
void raiseWarning(const QString &message=QString())
Definition: XmlStreamReader.cpp:86
AbstractAspect.h
AbstractAspect::Private::g_settings
static QSettings * g_settings
Definition: AspectPrivate.h:69
AbstractAspect::readCommentElement
bool readCommentElement(XmlStreamReader *reader)
Load comment from an XML element.
Definition: AbstractAspect.cpp:61
AbstractAspect
Base class of all persistent objects in a Project.
Definition: AbstractAspect.h:86
AbstractAspect::prepareAspectRemoval
virtual void prepareAspectRemoval(AbstractAspect *aspect)
Called before a child is removed.
Definition: AbstractAspect.h:300
AspectCreationTimeChangeCmd
Definition: aspectcommands.h:100
AbstractAspect::info
void info(const QString &text)
Implementations should call this whenever status information should be given to the user.
Definition: AbstractAspect.h:307